package admin

import (
	"exercise/application/yiran/app/libs"
	"exercise/application/yiran/app/model"
	"exercise/application/yiran/app/request/adminRequest"
	"fmt"
	"github.com/gin-gonic/gin"
	"strings"
)

type examTimeService struct {
}

// List 列表
func (*examTimeService) List(ctx *gin.Context, request *adminRequest.ExamTimeListRequest) (ret interface{}, err error) {
	schoolId, _ := ctx.Get("schoolId")
	list := make([]model.ExamTime, 0)
	paging := model.Paging{}
	paging.Page = request.Page
	paging.PageSize = request.PageSize

	total, err := model.NewDb("").FindAllAndCount(&list, "school_id = ? and delete_time = ? ", []interface{}{schoolId, 0}, model.OrderOrGroup{}, paging, []string{})

	if err != nil {
		return nil, fmt.Errorf("暂无数据：%w", err)
	}

	for _, value := range list {
		stuRange := make(map[string]interface{}, 0)
		err = libs.JsonDecode([]byte(value.StuRange), &stuRange)
		fmt.Printf("stuRange：%v \n", stuRange)
	}

	res := make([]map[string]interface{}, 0)
	for _, time := range list {
		stuRange := make(map[string]interface{}, 0)
		libs.JsonDecode([]byte(time.StuRange), &stuRange)
		item := make(map[string]interface{}, 0)
		item["id"] = time.Id
		item["stu_range"] = stuRange
		res = append(res, item)
	}

	return map[string]interface{}{
		"list":  res,
		"total": total,
	}, err
	return nil, err
}

// Add 新增
func (*examTimeService) Add(ctx *gin.Context, request *adminRequest.AddExamTimeRequest) (id interface{}, err error) {
	schoolId, _ := ctx.Get("schoolId")
	examTime := new(model.ExamTime)
	examTime.SchoolId = schoolId.(int64)
	examTime.Title = request.Title
	examTime.StartTime = request.StartTime
	examTime.EndTime = request.EndTime
	examTime.ExamType = request.ExamType
	examTime.JzwId = request.JzwId
	examTime.IsApp = request.IsApp
	examTime.SubTitle = request.SubTitle
	b := libs.JsonEncode(request.StuRange)
	examTime.StuRange = string(b)
	examTime.CreateTime = libs.CurrentTime()
	err = model.NewDb("").InsertRecord(examTime)
	if err != nil {
		return nil, err
	}
	return examTime.Id, nil
}

// Edit 编辑
func (*examTimeService) Edit(request *adminRequest.EditExamTimeRequest) (err error) {
	examTime := new(model.ExamTime)
	err = model.NewDb("").FindOne(examTime, "id = ? ", []interface{}{request.Id}, "*", []string{})
	if err != nil {
		return err
	}
	examTime.Title = request.Title
	examTime.StartTime = request.StartTime
	examTime.EndTime = request.EndTime
	examTime.ExamType = request.ExamType
	examTime.JzwId = request.JzwId
	examTime.IsApp = request.IsApp
	examTime.SubTitle = request.SubTitle

	b := libs.JsonEncode(request.StuRange)
	examTime.StuRange = string(b)

	err = model.NewDb("").SaveRecord(examTime)
	if err != nil {
		return err
	}
	return
}

// Detail 详情
func (*examTimeService) Detail(ctx *gin.Context) (res interface{}, err error) {
	id := ctx.Param("id")
	details := new(model.ExamTime)
	err = model.NewDb("").FindOne(details, "id = ? ", []interface{}{id}, "*", []string{})
	if err != nil {
		return nil, fmt.Errorf("数据异常：%w", err)
	}
	return details, err
}

func (rev *examTimeService) Deleted(ctx *gin.Context) error {
	schoolId, _ := ctx.Get("schoolId")
	id := ctx.Param("id")
	examTime := new(model.DeletedExamTime)
	err := model.NewDb("").FindOne(examTime, "id = ? ", []interface{}{id}, "id,delete_time", []string{})
	if err != nil {
		return err
	}
	examTime.DeleteTime = libs.CurrentTime()

	//清除缓存信息
	key := fmt.Sprintf("time:%d:%d", schoolId.(int64), libs.String2Int(id))
	err = model.NewRedis(0).Connect().Del(key).Err()

	timeIds, _ := rev.GetTimeIds(id)
	//清除预表 pid存在的清除pid的,不存在的清空自己的
	preAllocate := new(model.PreAllocate)
	model.NewDb("").DeleteRecord(preAllocate, "id in ?", timeIds)

	//清除考场学生student_exam,pid存在则要清空全部的
	studentExam := new(model.StudentExam)
	model.NewDb("").DeleteRecord(studentExam, "id in ?", timeIds)

	//删除考次
	err = model.NewDb("").SaveRecord(examTime)
	return err
}

// GetWhereByStuRange  获取where中配置的学生范围条件
func (*examTimeService) GetWhereByStuRange(time *model.ExamTime, year int) (sql string, where []interface{}) {
	sql = "year = ? "
	where = make([]interface{}, 0)
	where = append(where, year)

	stuRange := make(map[string]interface{}, 0)
	_ = libs.JsonDecode([]byte(time.StuRange), &stuRange)
	for key, val := range stuRange {

		if val == nil {
			continue
		}

		b := libs.IsSlice(val)

		if b == true {
			sql += " AND " + key + " IN ? "
			where = append(where, val)
			continue
		}

		sql += " AND " + key + " = ? "
		where = append(where, val)
	}

	return sql, where
}

// GetWhereByJzwRoom 筛选建筑物id或者房间id
func (examTimeService) GetWhereByJzwRoom(time *model.ExamTime, schoolId interface{}) (sql string, where []interface{}) {
	where = make([]interface{}, 0)
	sql += " school_id = ? "
	where = append(where, schoolId)
	if time.RoomId != "" && time.JzwId != "" {
		sql += " AND ( id IN ? OR jzw_id IN ? )"

		where = append(where, libs.String2IntSlice(strings.Split(time.RoomId, ",")), libs.String2IntSlice(strings.Split(time.JzwId, ",")))
	} else {
		if time.RoomId != "" {
			sql += " AND id IN ?"
			where = append(where, libs.String2IntSlice(strings.Split(time.RoomId, ",")))
		}

		if time.JzwId != "" {
			sql += " AND jzw_id IN ? "
			where = append(where, libs.String2IntSlice(strings.Split(time.JzwId, ",")))
		}
	}
	return sql, where
}

// GetTimeIds 获取所有timeId
func (examTimeService) GetTimeIds(id interface{}) (ids []interface{}, err error) {

	query := model.NewDb("").Query()
	details := make(map[string]interface{}, 0)
	examTimeTable := new(model.ExamTime)
	err = query.Model(examTimeTable).Where("id = ?", id).Select("id,pid").First(&details).Error
	if err != nil {
		return nil, err
	}
	timeId, _ := details["id"]
	pid, _ := details["pid"]
	ids = make([]interface{}, 0)
	if pid.(int64) != 0 { //获取pid下的所有Id 且包括pid本省
		list := make([]map[string]interface{}, 0)
		err = query.Model(examTimeTable).Where("pid = ?", pid).Select("id,pid").Find(&list).Error
		for _, m := range list {
			timeId, _ = m["id"]
			ids = append(ids, timeId)
		}
		ids = append(ids, pid)
	} else {
		ids = append(ids, timeId)
	}
	return ids, nil
}

// AddCache 新增缓存
func (rev *examTimeService) AddCache(ctx *gin.Context) error {
	id := ctx.Param("id")
	schoolId, _ := ctx.Get("schoolId")
	details := new(model.ExamTime)
	err := model.NewDb("").FindOne(details, "id = ? ", []interface{}{id}, "*", []string{})

	key := fmt.Sprintf("time:%d:%d", schoolId.(int64), libs.String2Int(id))

	m := libs.StructToMap(details)
	err = model.NewRedis(0).Connect().HMSet(key, m).Err()

	ret, _ := model.NewRedis(0).Connect().HGet(key, "is_app").Result()
	fmt.Printf("ret %v \n", ret)

	return err
}

// CopyTime 复制考次
func (rev examTimeService) CopyTime(ctx *gin.Context) error {
	id := ctx.Param("id")
	details := new(model.ExamTime)
	_ = model.NewDb("").FindOne(details, "id = ?", []interface{}{id}, "*", []string{})

	examTime := new(model.ExamTime)
	examTime.Pid = libs.String64Int(id)
	examTime.SchoolId = details.SchoolId
	examTime.Title = details.Title
	examTime.StartTime = details.StartTime
	examTime.EndTime = details.EndTime
	examTime.ExamType = details.ExamType
	examTime.JzwId = details.JzwId
	examTime.RoomId = details.RoomId
	examTime.IsApp = details.IsApp
	examTime.SubTitle = details.SubTitle
	examTime.StuRange = details.StuRange
	examTime.StuNumber = details.StuNumber
	examTime.CreateTime = libs.CurrentTime()

	model.NewDb("").InsertRecord(examTime)
	return nil
}

func NewExamTimeService() *examTimeService {
	return &examTimeService{}
}
